package com.company.Thread.DelayQueue;

import java.util.Map;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class DelayOrderQueueManager {

    private final static int DEFAULT_THREAD_NUM = 5;
    private static int thread_num = DEFAULT_THREAD_NUM;
    // 固定大小线程池  
    private ExecutorService executor;
    // 守护线程  
    private Thread daemonThread;
    // 延时队列  
    private DelayQueue<DelayTask<?>> delayQueue;

    /**
     * 单例模式，返回队列管理实例
     */
    private static DelayOrderQueueManager instance = new DelayOrderQueueManager();

    private DelayOrderQueueManager() {
        executor = Executors.newFixedThreadPool(thread_num);
        delayQueue = new DelayQueue<>();
        init();
    }

    public static DelayOrderQueueManager getInstance() {
        return instance;
    }

    /**
     * 队列管理类初始化
     */
    public void init() {
    	daemonThread = new Thread(() -> {
            execute();
        });

        daemonThread.setName("DelayQueueMonitor");
        daemonThread.start();
    }

    private void execute() {
        while (true) {
            Map<Thread, StackTraceElement[]> map = Thread.getAllStackTraces();
            System.out.println("当前存活线程数量:" + map.size());
            int taskNum = delayQueue.size();
            System.out.println("当前延时任务数量:" + taskNum);
            try {
                // 从延时队列中获取任务  
                DelayTask<?> DelayTask = delayQueue.take();
                if (DelayTask != null) {
                    Runnable task = DelayTask.getTask();
                    if (null == task) {
                        continue;
                    }
                    // 提交到线程池执行task  
                    executor.execute(task);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 添加任务
     *
     * @param task 任务实例化对象
     * @param time 任务延后时间
     * @param unit 时间单位
     * @author zhangyan
     * @date 2020年2月20日 下午8:43:28
     */
    public void put(Runnable task, long time, TimeUnit unit) {
        // 获取延时时间  
        long timeout = TimeUnit.NANOSECONDS.convert(time, unit);

        DelayTask<?> delayTask = new DelayTask<>(timeout, task);
        delayQueue.put(delayTask);
    }

    /**
     * 删除任务
     *
     * @param task
     * @return
     */
    public boolean removeTask(DelayTask<?> task) {
        return delayQueue.remove(task);
    }
}
